﻿using Core.DataAccess.Model;
using Core.Framework;
using Dapper;
using Local.Interface;
using System;
using System.Collections.Generic;

namespace Local.Implement
{
    public class NodeInstallPackage : INodeInstallPackage
    {
        private IDBFactory iDBFactory;

        public NodeInstallPackage(IDBFactory iDBFactory)
        {
            this.iDBFactory = iDBFactory;
        }


        public MethodResult<int> Add(NodePackage function)
        {
            // 向Kafka发布安装消息
            // 所有的 Solis 订阅该消息
            // Solis 启动时去 扫描本地 pages目录， 安装未安装的 服务

            // 添加数据库
            // 发布消息
            // Solis 开始安装 （维护一个安装失败的包，定期去重试）

            // 不向客户端时时反馈

            var result = new MethodResult<int>();

            using (var conn = this.iDBFactory.Create(DatabaseType.Function))
            {
                try
                {
                    var key = conn.Insert(function);
                    if (key > 0)
                    {
                        result.IsFinished = true;
                        result.Data = (int)key;
                    }
                    else
                    {
                        result.Discription = "系统异常";
                    }
                }
                catch (Exception ex)
                {
                    result.Discription = ex.Message;
                }
            }

            return result;
        }

        public MethodResult<Pagination> GetNodePackageList(Pagination pagination)
        {
            var result = new MethodResult<Pagination>();

            using (var conn = this.iDBFactory.Create(DatabaseType.Function))
            {
                try
                {
                    pagination.Data = conn.Query<NodePackage>("select * from [NodePackage]");
                    pagination.records = conn.RecordCount<NodePackage>();
                    result.IsFinished = true;
                    result.Data = pagination;
                }
                catch (Exception ex)
                {
                    result.Discription = ex.Message;
                }
            }

            return result;
        }


        public void InstallError(int id)
        {
            using (var conn = this.iDBFactory.Create(DatabaseType.Function))
            {
                conn.Execute($"update [NodePackage] set isInstallComplete = 0, reTryCount +=1,lastReTryTime = getdate() where id = {id}");
            }
        }

        public void InstallSuccess(int id)
        {
            using (var conn = this.iDBFactory.Create(DatabaseType.Function))
            {
                conn.Execute($"update [NodePackage] set isInstallComplete = 1,lastReTryTime = getdate() where id = {id}");
            }
        }

        public void InstallPackages(Action<KeyValuePair<string, string>> action, params string[] packages)
        {
            if (packages.Length > 0)
            {
                using (var conn = this.iDBFactory.Create(DatabaseType.Function))
                {
                    foreach (var package in packages)
                    {
                        var packName = string.Empty;
                        var packVerstion = string.Empty;
                        if (package.IndexOf("@") > -1)
                        {
                            var arr = package.Split("@");
                            packName = arr[0];
                            packVerstion = arr[1];
                        }
                        else
                        {
                            packName = package;
                        }

                        var entity = conn.QueryFirstOrDefault<NodePackage>("select id from [NodePackage] where drName= @drName and packageName=@packageName and version=@version", new
                        {
                            drName = package,
                            packageName = packName,
                            version = packVerstion
                        });

                        // 不存在
                        if (entity == null)
                        {
                            var model = new NodePackage();
                            model.drName = package;
                            model.packageName = packName;
                            model.version = packVerstion;
                            model.reTryCount = 0;
                            model.isInstallComplete = false;
                            var key = conn.Insert(model);

                            if (key > 0)
                            {
                                // 发布消息
                                var command = string.Empty;
                                if (!string.IsNullOrWhiteSpace(model.version))
                                {
                                    command = $"npm i {model.drName}@npm:{model.packageName}@{model.version}";
                                }
                                else
                                {
                                    command = $"npm i {model.packageName}";
                                }


                                action.Invoke(new KeyValuePair<string, string>(key.ToString(), command));
                            }

                        }

                    }
                }

            }

        }


    }
}
